{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Build a biGRU neural network model\n",
    "\n",
    "In this notebook, we are going to build a bidirectional Gated Recurrent Unit neural network model that will be capable of predicting with certain accuracy the future price movement of Stock Indexes, ETFs, Currencies or Commodities (whether the price will go up, down or stall). The accuracy of the model's predictions, especially in deep neural network strongly depends on the amount of training data. <b>I would like to emphasise that in this notebook the model will be trained on a very small dataset (just to show the process), thus the resulting performance of the model presented below deviates from its real capabilities</b>.\n",
    "\n",
    "Data is collected from various sources, sometimes there is no historical data available, thus the gathering of data is conducted mainly in real-time. As soon as the dataset grows to a decent size, the model will be one more time trained, which should result in better prediction power.\n",
    "\n",
    "The model is going to be trained on the 5 minute interval data (from MySQL/MariaDB database) that comprises the following input features:\n",
    "- The SPDR S&P 500 order book (aggregated size of resting displayed orders at a price and side)\n",
    "- Weighted average for bid's and ask's side orders\n",
    "- Volume Imbalance\n",
    "- Delta indicator\n",
    "- Bid-Ask Spread\n",
    "- Economic indicators such as Nonfarm Payrolls, Unemployment Rate, Building Permits, Core Retail Sales and others\n",
    "- Commitment of Traders reports data\n",
    "- CBOE Volatility Index\n",
    "- Open, high, low, close prices, volume and wick percentage\n",
    "- Bollinger Bands\n",
    "- Stochastic Oscillator\n",
    "- Average True Range\n",
    "- Volume, price and Delta indicator moving averages\n",
    "- The day of the week, week of the month, start session"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This is the multi-label classification problem, in which the target variables are determined using following manner:\n",
    "\n",
    "|                Condition                    |  up1  |  up2  | down1 | down2 |\n",
    "| :------------------------------------------:|:-----:|:-----:|:-----:|:-----:|\n",
    "| 8th bar p8_close >= p0_close + (n1 * ATR)   |   1   |   0   |   0   |   0   |\n",
    "| 15th bar p15_close >= p0_close + (n2 * ATR) |   0   |   1   |   0   |   0   |\n",
    "| 8th bar p8_close <= p0_close - (n1 * ATR)   |   0   |   0   |   1   |   0   |\n",
    "| 15th bar p15_close <= p0_close - (n2 * ATR) |   0   |   0   |   0   |   1   |\n",
    "\n",
    "In this notebook we used the following ATR factors:\n",
    "- n1 = 1.5\n",
    "- n2 = 3\n",
    "\n",
    "You can generate different target variables by modifying <i>target_statement</i> in <i>create_database.py</i> file (use different condition or ATR factors)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Building and training the model\n",
    "\n",
    "Let's start with importing all indispensable libraries."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "from torch.utils.data import DataLoader\n",
    "from torch import device\n",
    "import numpy as np\n",
    "import matplotlib.pyplot as plt\n",
    "import seaborn as sns\n",
    "from sklearn.metrics import accuracy_score, hamming_loss, fbeta_score, multilabel_confusion_matrix\n",
    "from sql_pytorch_dataloader import MySQLChunkLoader, MySQLBatchLoader, window_indices, TrainValTestSplit\n",
    "import mysql.connector\n",
    "from mysql.connector import errorcode\n",
    "from config import mysql_user, mysql_password, mysql_hostname, mysql_database_name, mysql_table_name\n",
    "from create_database import join_statement as db_x_query\n",
    "import warnings\n",
    "warnings.filterwarnings('ignore')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can print the db_x_query to see which columns (independent variables) are included in the SQL statement."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [],
   "source": [
    "# print(db_x_query)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To choose different set of input variables, simply modify the db_x_query"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [],
   "source": [
    "# db_x_query = \"SELECT sd.bid_0_size, sd.bid_1_size, sd.bid_2_size, sd.bid_3_size, sd.bid_4_size, sd.bid_5_size, sd.bid_6_size, sd.bid_1, sd.bid_2, sd.bid_3, sd.bid_4, sd.bid_5, sd.bid_6, sd.ask_0_size, sd.ask_1_size, sd.ask_2_size, sd.ask_3_size, sd.ask_4_size, sd.ask_5_size, sd.ask_6_size, sd.ask_1, sd.ask_2, sd.ask_3, sd.ask_4, sd.ask_5, sd.ask_6, sd.bids_ord_WA, sd.asks_ord_WA, sd.vol_imbalance, sd.delta, sd.micro_price, sd.spread, sd.session_start, sd.day_1, sd.day_2, sd.day_3, sd.day_4, sd.week_1, sd.week_2, sd.week_3, sd.week_4, sd.VIX, sd.1_open, sd.2_high, sd.3_low, sd.4_close, sd.5_volume, sd.wick_prct, sd.Asset_long_pos, sd.Asset_long_pos_change, sd.Asset_long_open_int, sd.Asset_short_pos, sd.Asset_short_pos_change, sd.Asset_short_open_int, sd.Leveraged_long_pos, sd.Leveraged_long_pos_change, sd.Leveraged_long_open_int, sd.Leveraged_short_pos, sd.Leveraged_short_pos_change, sd.Leveraged_short_open_int, sd.Crude_Oil_Inventories_Actual, sd.Crude_Oil_Inventories_Prev_actual_diff, sd.Crude_Oil_Inventories_Forc_actual_diff, sd.ISM_Non_Manufacturing_PMI_Actual, sd.ISM_Non_Manufacturing_PMI_Prev_actual_diff, sd.ISM_Non_Manufacturing_PMI_Forc_actual_diff, sd.ISM_Non_Manufacturing_Employment_Actual, sd.ISM_Non_Manufacturing_Employment_Prev_actual_diff, sd.ISM_Non_Manufacturing_Employment_Forc_actual_diff, sd.Services_PMI_Actual, sd.Services_PMI_Prev_actual_diff, sd.Services_PMI_Forc_actual_diff, sd.ADP_Nonfarm_Employment_Change_Actual, sd.ADP_Nonfarm_Employment_Change_Prev_actual_diff, sd.ADP_Nonfarm_Employment_Change_Forc_actual_diff, sd.Core_CPI_Actual, sd.Core_CPI_Prev_actual_diff, sd.Core_CPI_Forc_actual_diff, sd.Fed_Interest_Rate_Decision_Actual, sd.Fed_Interest_Rate_Decision_Prev_actual_diff, sd.Fed_Interest_Rate_Decision_Forc_actual_diff, sd.Building_Permits_Actual, sd.Building_Permits_Prev_actual_diff, sd.Building_Permits_Forc_actual_diff, sd.Core_Retail_Sales_Actual, sd.Core_Retail_Sales_Prev_actual_diff, sd.Core_Retail_Sales_Forc_actual_diff, sd.Retail_Sales_Actual, sd.Retail_Sales_Prev_actual_diff, sd.Retail_Sales_Forc_actual_diff, sd.JOLTs_Job_Openings_Actual, sd.JOLTs_Job_Openings_Prev_actual_diff, sd.JOLTs_Job_Openings_Forc_actual_diff, sd.Nonfarm_Payrolls_Actual, sd.Nonfarm_Payrolls_Prev_actual_diff, sd.Nonfarm_Payrolls_Forc_actual_diff, sd.Unemployment_Rate_Actual, sd.Unemployment_Rate_Prev_actual_diff, sd.Unemployment_Rate_Forc_actual_diff, bb.upper_BB_dist, bb.lower_BB_dist, vol.vol_MA6, vol.vol_MA20, p.price_MA20, d.delta_MA12, so.stoch, ATR.ATR, pc.price_change FROM stock_data_joined sd JOIN bollinger_bands bb ON sd.Timestamp = bb.Timestamp JOIN vol_MA vol ON sd.Timestamp = vol.Timestamp JOIN price_MA p ON sd.Timestamp = p.Timestamp JOIN delta_MA d ON sd.Timestamp = d.Timestamp JOIN stochastic_oscillator so ON sd.Timestamp = so.Timestamp JOIN ATR ON sd.Timestamp = ATR.Timestamp JOIN price_change pc ON sd.Timestamp = pc.Timestamp;\""
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next step is to connect to MySQL/MariadDB server and create a cursor object that will be used to execute SQL statements."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Connect to MySQL server\n",
    "try:\n",
    "    cnx = mysql.connector.connect(host=mysql_hostname, user=mysql_user, password=mysql_password)\n",
    "except mysql.connector.Error as err:\n",
    "    if err.errno == errorcode.ER_ACCESS_DENIED_ERROR:\n",
    "        print(\"User name or password incorrect\")\n",
    "    else:\n",
    "        print(err)\n",
    "    # Close connection\n",
    "    cnx.close()\n",
    "    print('Connection closed')\n",
    "\n",
    "# Instantiate cursor object\n",
    "db_cursor = cnx.cursor()\n",
    "\n",
    "# Use given database\n",
    "db_cursor.execute(\"USE {};\".format(mysql_database_name))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we can specify target variables, chunk_size and window size."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "metadata": {},
   "outputs": [],
   "source": [
    "y_fields = \"up1, up2, down1, down2\"\n",
    "chunk_size = 100\n",
    "window = 30"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We have to count the number of positive and negative examples within each class in order to be able to compare those values within one class and between classes because the strong imbalance of positive or negative examples either within a single class or between classes can encourage the model to predict most frequently occurring result."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Counts the positive examples within each target class\n",
    "target_counts = []\n",
    "\n",
    "for target in y_fields.split(\", \"):\n",
    "    db_cursor.execute(\"SELECT SUM({}) FROM target;\".format(target))\n",
    "    target_counts.append(int(db_cursor.fetchall()[0][0]))\n",
    "    \n",
    "# Counts the total number of examples\n",
    "db_cursor.execute(\"SELECT COUNT(ID) FROM target;\")\n",
    "total_examples = db_cursor.fetchall()[0][0]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Total number of exampls:  3980\n",
      "Class up1: 948 positive and 3032 negative examples\n",
      "Class up2: 575 positive and 3405 negative examples\n",
      "Class down1: 917 positive and 3063 negative examples\n",
      "Class down2: 672 positive and 3308 negative examples\n"
     ]
    }
   ],
   "source": [
    "print(\"Total number of exampls: \", total_examples)\n",
    "\n",
    "for i in range(len(target_counts)):\n",
    "    print(\"Class {}: {} positive and {} negative examples\".format(y_fields.split(\", \")[i],target_counts[i],\\\n",
    "                                                                  total_examples - target_counts[i]))"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We can see that we have the imbalance of positive examples between classes - class up1 has 947 positive data point, while class up2 has only 575 positive examples. To deal with that problem we should rescale the losses calculated by loss function by using following weight tensor [3980/947, 3980/575, 3980/917, 3980/672] to penalize the dominating classes less and weight the loss of minority classes higher - increase the impact of the underrepresented classes.\n",
    "\n",
    "To tackle the problem of strong imbalance of positive and negative examples within the single class we should specify the tensor of the weights of positive examples - pos_weight = [3033/947, 3405/575, 3063/917, 3308/672] than can be passed as an argument to BCEWithLogitsLoss function."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "metadata": {},
   "outputs": [],
   "source": [
    "weight, pos_weight = [], []\n",
    "\n",
    "for i in range(len(target_counts)):\n",
    "    weight.append(total_examples/target_counts[i])\n",
    "    pos_weight.append((total_examples - target_counts[i])/target_counts[i])"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below we will instantiate MySQLChunkLoader object that is responsible for generating indices of database rows that form a chunk of MySQL/MariaDB database parameterized by chunk_size (chunking is used to diminish memory usage while parsing).\n",
    "Chunk loader also calculates data chunk's normalization parameters - minimum and maximum, pass them to MySQLBatchLoader and save locally. Normalization parameters subsequently can be used by MySQLBatchLoader to normalize training batches (according to MIN and MAX of a chunk to which given batch belongs to) as well as to normalize validation and test sets during evaluation or real-time inference."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 9,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Instantiate MySQLChunkLoader object\n",
    "chunk_loader = MySQLChunkLoader(cursor=db_cursor, table=mysql_table_name, db_x_query=db_x_query, \n",
    "                                chunk_size=chunk_size, window=window)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "TrainValTestSplit performs Train/Validation/Test splitting of a set of data chunks, which means that val_size and test_size parameters refere to number of chunks (not to total number of data points!)\n",
    "\n",
    "For instance, If we have dataset that consits of 16 chunks and we use val_size=0.1 and test_size=0.1 then spliting \n",
    "will be performed in following manner: \n",
    "- train_set -> will contain 0.8 * 16 chunks = 12 chunks\n",
    "- val_size -> (0.1 * 16) + 1 = 2 chunks\n",
    "- test_size -> (0.1 * 16) + 1 = 2 chunks"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Split dataset into training, validation and test sets\n",
    "split = TrainValTestSplit(chunk_loader, val_size=0.12, test_size=0.08)\n",
    "train_set, val_set, test_set = split.get_sets()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "MySQLBatchLoader consecutively generates indices of database rows in a sliding window manner to be read from\n",
    "chunk of a MySQL/MariaDB database.\n",
    "\n",
    "Example of generating sliding windows within chunks of data:\n",
    "\n",
    "| DB table | Table chunks | Sliding windows |\n",
    "|:--:|:--:|:--:|\n",
    "|1. |  1. | 1., 2. |\n",
    "|2. | 2. | -------- |\n",
    "|3. | 3. | 2., 3. |\n",
    "|4. | --------| -------- |\n",
    "|5. | 3. |3., 4. |\n",
    "|   | 4. | -------- |\n",
    "|   | 5. | 4., 5. |"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "We have to check out how batches that we created look like before we pass them into the model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 11,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "tensor([[[0.0556, 0.0111, 0.0667,  ..., 0.0000, 0.0398, 0.7156],\n",
      "         [0.0111, 0.0556, 0.0556,  ..., 0.0526, 0.0000, 0.8414],\n",
      "         [0.0556, 0.0111, 0.0556,  ..., 0.0000, 0.0588, 0.7143],\n",
      "         ...,\n",
      "         [0.0556, 0.0556, 0.0111,  ..., 0.2147, 0.4671, 0.8742],\n",
      "         [0.0556, 0.0556, 0.0111,  ..., 0.5147, 0.5303, 0.9594],\n",
      "         [0.0556, 0.0111, 0.0111,  ..., 0.2628, 0.5804, 0.7038]],\n",
      "\n",
      "        [[0.0111, 0.0556, 0.0556,  ..., 0.0526, 0.0000, 0.8414],\n",
      "         [0.0556, 0.0111, 0.0556,  ..., 0.0000, 0.0588, 0.7143],\n",
      "         [0.0556, 0.0556, 0.0556,  ..., 0.0000, 0.1202, 0.6514],\n",
      "         ...,\n",
      "         [0.0556, 0.0556, 0.0111,  ..., 0.5147, 0.5303, 0.9594],\n",
      "         [0.0556, 0.0111, 0.0111,  ..., 0.2628, 0.5804, 0.7038],\n",
      "         [0.0111, 0.0556, 0.0556,  ..., 0.4820, 0.5978, 0.9109]]])\n",
      "--------------\n",
      "tensor([[[0., 0., 0., 0.]],\n",
      "\n",
      "        [[0., 0., 0., 0.]]])\n",
      "\n",
      "NEXT BATCH\n"
     ]
    }
   ],
   "source": [
    "# It is possible to loop through all batches only once. Thus the split.get_sets() method\n",
    "# have to be called always befor looping through (training, validation or test) set in order to generate\n",
    "# indices and norm_params.\n",
    "for indices, norm_params in train_set:\n",
    "\n",
    "    train_loader = DataLoader(MySQLBatchLoader(indices=indices, norm_params=norm_params, cursor=db_cursor,\n",
    "                                   table=mysql_table_name, db_x_query=db_x_query, y_fields=y_fields,\n",
    "                                   window=window), batch_size=2)\n",
    "    for batch in train_loader:\n",
    "        x, y = batch\n",
    "        # x size: batch_size, seq_len, n_features\n",
    "        print(x)\n",
    "        print(\"--------------\")\n",
    "        # y size: batch_size, 1, n_classes\n",
    "        print(y)\n",
    "        break\n",
    "        \n",
    "    print(\"\\nNEXT BATCH\")\n",
    "    break"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Below we will check how the train/val/test splitting was performed."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Number of chunks in dataset:  41\n",
      "Number of chunks in training set:  32\n",
      "Number of chunks in validation set:  5\n",
      "Number of chunks in test set:  4\n"
     ]
    }
   ],
   "source": [
    "print(\"Number of chunks in dataset: \", split.dataset_len + 1)\n",
    "print(\"Number of chunks in training set: \", split.train_end_idx)\n",
    "print(\"Number of chunks in validation set: \", split.val_end_idx - split.train_end_idx)\n",
    "print(\"Number of chunks in test set: \", split.test_end_idx - split.val_end_idx)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Next step is to build the biGRU model."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "metadata": {},
   "outputs": [],
   "source": [
    "class BiGRU(nn.Module):\n",
    "    \"\"\"BiDirectional GRU neural network model.\n",
    "        \n",
    "    Parameters\n",
    "    ----------\n",
    "    hidden_size: int\n",
    "        Number of features in the hidden state.\n",
    "    n_features: int\n",
    "        Number of the input features.\n",
    "    output_size: int\n",
    "        Number of classes.\n",
    "    n_layers: int, optional (default=1)\n",
    "        Number of stacked recurrent layers.\n",
    "    clip: int, optional (default=50)\n",
    "        Max norm of the gradients.\n",
    "    dropout: float, optional (default=0.2)\n",
    "        Probability of an element of the tensor to be zeroed.\n",
    "    spatial_dropout: boolean, optional (default=True)\n",
    "        Whether to use the spatial dropout.\n",
    "    bidirectional: boolean, optional (default=True)\n",
    "        Whether to use the bidirectional GRU.\n",
    "\n",
    "    \"\"\"\n",
    "    \n",
    "    def __init__(self, hidden_size, n_features, output_size, n_layers=1, clip=50, dropout=0.2,\n",
    "                 spatial_dropout=True, bidirectional=True):\n",
    "        \n",
    "        # Inherit everything from the nn.Module\n",
    "        super(BiGRU, self).__init__()\n",
    "        \n",
    "        # Initialize attributes\n",
    "        self.hidden_size = hidden_size\n",
    "        self.n_features = n_features\n",
    "        self.output_size = output_size\n",
    "        self.n_layers = n_layers\n",
    "        self.clip = clip\n",
    "        self.dropout_p = dropout\n",
    "        self.spatial_dropout = spatial_dropout\n",
    "        self.bidirectional = bidirectional\n",
    "        self.n_directions = 2 if self.bidirectional else 1\n",
    "        \n",
    "        # Initialize layers\n",
    "        self.dropout = nn.Dropout(self.dropout_p)\n",
    "        if self.spatial_dropout:\n",
    "            self.spatial_dropout1d = nn.Dropout2d(self.dropout_p)\n",
    "            \n",
    "        self.gru = nn.GRU(self.n_features, self.hidden_size, num_layers=self.n_layers, \n",
    "                          dropout=(0 if n_layers == 1 else self.dropout_p), batch_first=True,\n",
    "                          bidirectional=self.bidirectional)\n",
    "        \n",
    "        # Linear layer input size is equal to hidden_size * 3, becuase\n",
    "        # we will concatenate max_pooling ,avg_pooling and last hidden state\n",
    "        self.linear = nn.Linear(self.hidden_size * 3, self.output_size)\n",
    "\n",
    "        \n",
    "    def forward(self, input_seq, hidden=None):\n",
    "        \"\"\"Forward propagates through the neural network model.\n",
    "        \n",
    "        Parameters\n",
    "        ----------\n",
    "        input_seq: torch.Tensor\n",
    "            Batch of input sequences.\n",
    "        hidden: torch.FloatTensor, optional (default=None)\n",
    "            Tensor containing initial hidden state.\n",
    "            \n",
    "        Returns\n",
    "        -------\n",
    "        torch.Tensor\n",
    "            Logits - vector of raw predictions in range (-inf, inf). Probability of 0.5 corresponds\n",
    "            to a logit of 0. Positive logits correspond to probabilities greater than 0.5, while negative\n",
    "            to probabilities less than 0.5.\n",
    "        \n",
    "        \"\"\"\n",
    "        # Extract batch_size\n",
    "        self.batch_size = input_seq.size(0)\n",
    "        \n",
    "        # Sequence length\n",
    "        self.input_length = input_seq.size(1)\n",
    "        \n",
    "        if self.spatial_dropout:\n",
    "            # Convert to (batch_size, n_features, seq_length)\n",
    "            input_seq = input_seq.permute(0, 2, 1)\n",
    "            input_seq = self.spatial_dropout1d(input_seq)\n",
    "            # Convert back to (batch_size, seq_length, n_features)\n",
    "            input_seq = input_seq.permute(0, 2, 1)\n",
    "        else:\n",
    "            input_seq = self.dropout(input_seq)\n",
    "                \n",
    "        # GRU input/output shapes, if batch_first=True\n",
    "        # Input: (batch_size, seq_len, n_features)\n",
    "        # Output: (batch_size, seq_len, hidden_size*num_directions)\n",
    "        # Number of directions = 2 when used bidirectional, otherwise 1\n",
    "        # shape of hidden: (n_layers x num_directions, batch_size, hidden_size)\n",
    "        # Hidden state defaults to zero if not provided\n",
    "        gru_out, hidden = self.gru(input_seq, hidden)\n",
    "        # gru_out: tensor containing the output features h_t from the last layer of the GRU\n",
    "        # gru_out comprises all the hidden states in the last layer (\"last\" depth-wise, not time-wise)\n",
    "        # For biGRu gru_out is the concatenation of a forward GRU representation and a backward GRU representation\n",
    "        # hidden (h_n) comprises the hidden states after the last timestep\n",
    "        \n",
    "        # Extract and sum last hidden state\n",
    "        # Input hidden shape: (n_layers x num_directions, batch_size, hidden_size)\n",
    "        # Separate hidden state layers\n",
    "        hidden = hidden.view(self.n_layers, self.n_directions, self.batch_size, self.hidden_size)\n",
    "        last_hidden = hidden[-1]\n",
    "        # last hidden shape (num_directions, batch_size, hidden_size)\n",
    "        # Sum the last hidden state of forward and backward layer\n",
    "        last_hidden = torch.sum(last_hidden, dim=0)\n",
    "        # Summed last hidden shape (batch_size, hidden_size)\n",
    "              \n",
    "        # Sum the gru_out along the num_directions\n",
    "        if self.bidirectional:\n",
    "            gru_out = gru_out[:,:,:self.hidden_size] + gru_out[:,:,self.hidden_size:]\n",
    "        \n",
    "        # Select the maximum value over each dimension of the hidden representation (max pooling)\n",
    "        # Permute the input tensor to dimensions: (batch_size, hidden, seq_len)\n",
    "        # Output dimensions: (batch_size, hidden_size)\n",
    "        max_pool = F.adaptive_max_pool1d(gru_out.permute(0,2,1), (1,)).view(self.batch_size,-1)\n",
    "        \n",
    "        # Consider the average of the representations (mean pooling)\n",
    "        # Sum along the batch axis and divide by the corresponding length (FloatTensor)\n",
    "        # Output shape: (batch_size, hidden_size)\n",
    "        avg_pool = torch.sum(gru_out, dim=1) / torch.FloatTensor([self.input_length])\n",
    "\n",
    "        # Concatenate max_pooling, avg_pooling and last hidden state tensors\n",
    "        concat_out = torch.cat([last_hidden, max_pool, avg_pool], dim=1)\n",
    "\n",
    "        # concat_out = self.dropout(concat_out)\n",
    "        # output_size: batch_size, output_size\n",
    "        out = self.linear(concat_out)\n",
    "        return out\n",
    "    \n",
    "    \n",
    "    def add_loss_fn(self, loss_fn):\n",
    "        \"\"\"Add loss function to the model.\n",
    "        \n",
    "        \"\"\"\n",
    "        self.loss_fn = loss_fn\n",
    "        \n",
    "\n",
    "    def add_optimizer(self, optimizer):\n",
    "        \"\"\"Add optimizer to the model.\n",
    "        \n",
    "        \"\"\"\n",
    "        self.optimizer = optimizer\n",
    "        \n",
    "        \n",
    "    def add_device(self, device=torch.device('cpu')):\n",
    "        \"\"\"Specify the device.\n",
    "        \n",
    "        \"\"\"\n",
    "        self.device = device\n",
    "    \n",
    "    \n",
    "    def train_model(self, train_iterator):\n",
    "        \"\"\"Performs single training epoch.\n",
    "        \n",
    "        Parameters\n",
    "        ----------\n",
    "        train_iterator: torch.utils.data.dataloader.DataLoader\n",
    "            Pytorch dataloader of MySQLBatchLoader dataset.\n",
    "            \n",
    "        Returns\n",
    "        -------\n",
    "        accuracies: float\n",
    "            Mean accuracy.\n",
    "        hamm_losses: float\n",
    "            Mean Hamming loss.\n",
    "        losses: float\n",
    "            Mean loss.\n",
    "        fbetas_list: list\n",
    "            Mean fbeta score within each class.\n",
    "            \n",
    "        \"\"\"\n",
    "        self.train()\n",
    "        \n",
    "        losses = []\n",
    "        accuracies = []\n",
    "        hamm_losses = []\n",
    "        fbetas_list = []\n",
    "            \n",
    "        for input_seq, target in train_iterator:\n",
    "            # input_seq size: batch_size, seq_len, n_features\n",
    "            # target size: batch_size, 1, n_classes           \n",
    "            # Reshape target to size: batch_size, n_classes\n",
    "            target = target.squeeze(1)\n",
    "\n",
    "            input_seq.to(self.device)\n",
    "            target.to(self.device)\n",
    "            \n",
    "            self.optimizer.zero_grad()\n",
    "\n",
    "            pred = self.forward(input_seq)\n",
    "\n",
    "            loss = self.loss_fn(pred, target)\n",
    "            \n",
    "            loss.backward()\n",
    "            losses.append(loss.data.cpu().numpy())\n",
    "            \n",
    "            # Clip gradients: gradients are modified in place\n",
    "            _ = nn.utils.clip_grad_norm_(self.parameters(), self.clip)\n",
    "            \n",
    "            self.optimizer.step()\n",
    "            \n",
    "            # Map logits to probabilities and extract labels using threshold (if nn.MultiLabelSoftMarginLoss())\n",
    "            # pred = torch.sigmoid(pred) > 0.5\n",
    "            \n",
    "            pred = pred > 0.5\n",
    "                        \n",
    "            ac_score = accuracy_score(target, pred)           \n",
    "            accuracies.append(ac_score)\n",
    "\n",
    "            hamm_loss = hamming_loss(target, pred)\n",
    "            hamm_losses.append(hamm_loss)\n",
    "            \n",
    "            fbeta = fbeta_score(target, pred, beta=0.5, average=None)\n",
    "            fbetas_list.append(fbeta)\n",
    "                              \n",
    "        return np.mean(accuracies), np.mean(hamm_losses), np.mean(losses), np.mean(fbetas_list, axis=0)\n",
    "    \n",
    "    \n",
    "    def evaluate_model(self, eval_iterator):\n",
    "        \"\"\"Perform the one evaluation epoch.\n",
    "        \n",
    "        Parameters\n",
    "        ----------\n",
    "        eval_iterator: torch.utils.data.dataloader.DataLoader\n",
    "            Pytorch dataloader of MySQLBatchLoader dataset.\n",
    "            \n",
    "        Returns\n",
    "        -------\n",
    "        accuracies: float\n",
    "            Mean accuracy.\n",
    "        hamm_losses: float\n",
    "            Mean Hamming loss.\n",
    "        fbetas_list: list\n",
    "            Mean fbeta score within each class.\n",
    "        pred_total: torch.LongTensor()\n",
    "            Tensor containing chunk's generated predictions \n",
    "        target_total: torch.LongTensor()\n",
    "            Tensor containing chunk's target variables.\n",
    "            \n",
    "        \"\"\"\n",
    "        self.eval()\n",
    "\n",
    "        losses = []\n",
    "        accuracies = []\n",
    "        hamm_losses = []\n",
    "        fbetas_list = []\n",
    "        pred_total = torch.LongTensor()\n",
    "        target_total = torch.LongTensor()\n",
    "        \n",
    "        with torch.no_grad():\n",
    "            for input_seq, target in eval_iterator:\n",
    "                target = target.squeeze(1)\n",
    "\n",
    "                input_seq.to(self.device)\n",
    "                target.to(self.device)\n",
    "\n",
    "                pred = self.forward(input_seq)\n",
    "\n",
    "                # loss = self.loss_fn(pred, target)\n",
    "                \n",
    "                # losses.append(loss.data.cpu().numpy())\n",
    "                \n",
    "                # Map logits to probabilities and extract labels using threshold (if nn.MultiLabelSoftMarginLoss())\n",
    "                # pred = torch.sigmoid(pred) > 0.5\n",
    "\n",
    "                pred = pred > 0.5\n",
    "                \n",
    "                ac_score = accuracy_score(target, pred)           \n",
    "                accuracies.append(ac_score)\n",
    "\n",
    "                hamm_loss = hamming_loss(target, pred)\n",
    "                hamm_losses.append(hamm_loss)\n",
    "\n",
    "                fbeta = fbeta_score(target, pred, beta=1, average=None)\n",
    "                fbetas_list.append(fbeta)\n",
    "                \n",
    "                pred_total = torch.cat([pred_total, pred.type(torch.LongTensor)], dim=0)\n",
    "                target_total = torch.cat([target_total, target.type(torch.LongTensor)], dim=0)\n",
    "        \n",
    "        return  np.mean(accuracies), np.mean(hamm_losses), np.mean(fbetas_list, axis=0), pred_total, target_total"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Now we will instantiate the model, add loss function, optimizer, and device to it and begin the training."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Start epoch [1/25]\n",
      "\n",
      "Epoch [1/25]: Train accuracy: 0.314, Hamming loss: 0.276, Loss: 6.142, fbeta: [0.05552083 0.04836806 0.02371528 0.04090278]\n",
      "\n",
      "Epoch [1/25]: Evaluation accuracy: 0.070, Eval Hamming loss: 0.489, Eval fbeta: [0.         0.         0.192      0.14933333]\n",
      "Evaluation Confusion matrix: \n",
      " [[[368   0]\n",
      "  [132   0]]\n",
      "\n",
      " [[412   0]\n",
      "  [ 88   0]]\n",
      "\n",
      " [[ 85 317]\n",
      "  [ 10  88]]\n",
      "\n",
      " [[  0 431]\n",
      "  [  0  69]]]\n",
      "\n",
      "Start epoch [2/25]\n",
      "\n",
      "Epoch [2/25]: Train accuracy: 0.346, Hamming loss: 0.255, Loss: 5.706, fbeta: [0.06607639 0.06072917 0.06034722 0.06868056]\n",
      "\n",
      "Epoch [2/25]: Evaluation accuracy: 0.140, Eval Hamming loss: 0.442, Eval fbeta: [0.176      0.15866667 0.13333333 0.10666667]\n",
      "Evaluation Confusion matrix: \n",
      " [[[219 149]\n",
      "  [ 52  80]]\n",
      "\n",
      " [[282 130]\n",
      "  [ 12  76]]\n",
      "\n",
      " [[221 181]\n",
      "  [ 38  60]]\n",
      "\n",
      " [[129 302]\n",
      "  [ 20  49]]]\n",
      "\n",
      "Start epoch [3/25]\n",
      "\n",
      "Epoch [3/25]: Train accuracy: 0.366, Hamming loss: 0.251, Loss: 5.473, fbeta: [0.07795139 0.07350694 0.07541667 0.08777778]\n",
      "\n",
      "Epoch [3/25]: Evaluation accuracy: 0.146, Eval Hamming loss: 0.426, Eval fbeta: [0.184 0.16  0.084 0.092]\n",
      "Evaluation Confusion matrix: \n",
      " [[[184 184]\n",
      "  [ 48  84]]\n",
      "\n",
      " [[231 181]\n",
      "  [ 11  77]]\n",
      "\n",
      " [[287 115]\n",
      "  [ 59  39]]\n",
      "\n",
      " [[202 229]\n",
      "  [ 26  43]]]\n",
      "\n",
      "Start epoch [4/25]\n",
      "\n",
      "Epoch [4/25]: Train accuracy: 0.361, Hamming loss: 0.248, Loss: 5.324, fbeta: [0.080625   0.08197917 0.08850694 0.09739583]\n",
      "\n",
      "Epoch [4/25]: Evaluation accuracy: 0.164, Eval Hamming loss: 0.411, Eval fbeta: [0.18533333 0.16       0.07733333 0.092     ]\n",
      "Evaluation Confusion matrix: \n",
      " [[[180 188]\n",
      "  [ 47  85]]\n",
      "\n",
      " [[221 191]\n",
      "  [ 11  77]]\n",
      "\n",
      " [[297 105]\n",
      "  [ 62  36]]\n",
      "\n",
      " [[239 192]\n",
      "  [ 26  43]]]\n",
      "\n",
      "Start epoch [5/25]\n",
      "\n",
      "Epoch [5/25]: Train accuracy: 0.372, Hamming loss: 0.244, Loss: 5.092, fbeta: [0.09878472 0.09371528 0.11159722 0.10444444]\n",
      "\n",
      "Epoch [5/25]: Evaluation accuracy: 0.170, Eval Hamming loss: 0.410, Eval fbeta: [0.184      0.16       0.08933333 0.08      ]\n",
      "Evaluation Confusion matrix: \n",
      " [[[169 199]\n",
      "  [ 47  85]]\n",
      "\n",
      " [[206 206]\n",
      "  [ 11  77]]\n",
      "\n",
      " [[301 101]\n",
      "  [ 58  40]]\n",
      "\n",
      " [[265 166]\n",
      "  [ 32  37]]]\n",
      "\n",
      "Start epoch [6/25]\n",
      "\n",
      "Epoch [6/25]: Train accuracy: 0.371, Hamming loss: 0.239, Loss: 4.991, fbeta: [0.10041667 0.09809028 0.11767361 0.11145833]\n",
      "\n",
      "Epoch [6/25]: Evaluation accuracy: 0.182, Eval Hamming loss: 0.403, Eval fbeta: [0.18133333 0.16       0.07866667 0.07333333]\n",
      "Evaluation Confusion matrix: \n",
      " [[[176 192]\n",
      "  [ 48  84]]\n",
      "\n",
      " [[200 212]\n",
      "  [ 11  77]]\n",
      "\n",
      " [[303  99]\n",
      "  [ 62  36]]\n",
      "\n",
      " [[284 147]\n",
      "  [ 35  34]]]\n",
      "\n",
      "Start epoch [7/25]\n",
      "\n",
      "Epoch [7/25]: Train accuracy: 0.380, Hamming loss: 0.237, Loss: 4.848, fbeta: [0.10430556 0.09659722 0.13135417 0.11774306]\n",
      "\n",
      "Epoch [7/25]: Evaluation accuracy: 0.222, Eval Hamming loss: 0.392, Eval fbeta: [0.18666667 0.16       0.072      0.07333333]\n",
      "Evaluation Confusion matrix: \n",
      " [[[175 193]\n",
      "  [ 47  85]]\n",
      "\n",
      " [[194 218]\n",
      "  [ 11  77]]\n",
      "\n",
      " [[309  93]\n",
      "  [ 65  33]]\n",
      "\n",
      " [[308 123]\n",
      "  [ 35  34]]]\n",
      "\n",
      "Start epoch [8/25]\n",
      "\n",
      "Epoch [8/25]: Train accuracy: 0.400, Hamming loss: 0.227, Loss: 4.700, fbeta: [0.11166667 0.10576389 0.13954861 0.13045139]\n",
      "\n",
      "Epoch [8/25]: Evaluation accuracy: 0.206, Eval Hamming loss: 0.402, Eval fbeta: [0.16933333 0.16266667 0.068      0.07066667]\n",
      "Evaluation Confusion matrix: \n",
      " [[[167 201]\n",
      "  [ 55  77]]\n",
      "\n",
      " [[191 221]\n",
      "  [ 10  78]]\n",
      "\n",
      " [[301 101]\n",
      "  [ 66  32]]\n",
      "\n",
      " [[317 114]\n",
      "  [ 36  33]]]\n",
      "\n",
      "Start epoch [9/25]\n",
      "\n",
      "Epoch [9/25]: Train accuracy: 0.409, Hamming loss: 0.224, Loss: 4.625, fbeta: [0.11878472 0.10763889 0.14321181 0.12630208]\n",
      "\n",
      "Epoch [9/25]: Evaluation accuracy: 0.224, Eval Hamming loss: 0.397, Eval fbeta: [0.172      0.14533333 0.07466667 0.07333333]\n",
      "Evaluation Confusion matrix: \n",
      " [[[171 197]\n",
      "  [ 54  78]]\n",
      "\n",
      " [[199 213]\n",
      "  [ 18  70]]\n",
      "\n",
      " [[299 103]\n",
      "  [ 64  34]]\n",
      "\n",
      " [[320 111]\n",
      "  [ 35  34]]]\n",
      "\n",
      "Start epoch [10/25]\n",
      "\n",
      "Epoch [10/25]: Train accuracy: 0.429, Hamming loss: 0.214, Loss: 4.436, fbeta: [0.12861111 0.11354167 0.15373264 0.13322917]\n",
      "\n",
      "Epoch [10/25]: Evaluation accuracy: 0.198, Eval Hamming loss: 0.404, Eval fbeta: [0.16666667 0.14666667 0.06533333 0.07066667]\n",
      "Evaluation Confusion matrix: \n",
      " [[[167 201]\n",
      "  [ 57  75]]\n",
      "\n",
      " [[187 225]\n",
      "  [ 17  71]]\n",
      "\n",
      " [[312  90]\n",
      "  [ 67  31]]\n",
      "\n",
      " [[317 114]\n",
      "  [ 36  33]]]\n",
      "\n",
      "Start epoch [11/25]\n",
      "\n",
      "Epoch [11/25]: Train accuracy: 0.433, Hamming loss: 0.209, Loss: 4.290, fbeta: [0.12875    0.11847222 0.15491319 0.13559028]\n",
      "\n",
      "Epoch [11/25]: Evaluation accuracy: 0.254, Eval Hamming loss: 0.376, Eval fbeta: [0.16533333 0.14666667 0.06533333 0.07066667]\n",
      "Evaluation Confusion matrix: \n",
      " [[[179 189]\n",
      "  [ 57  75]]\n",
      "\n",
      " [[214 198]\n",
      "  [ 17  71]]\n",
      "\n",
      " [[304  98]\n",
      "  [ 67  31]]\n",
      "\n",
      " [[341  90]\n",
      "  [ 36  33]]]\n",
      "\n",
      "Start epoch [12/25]\n",
      "\n",
      "Epoch [12/25]: Train accuracy: 0.433, Hamming loss: 0.208, Loss: 4.195, fbeta: [0.13565972 0.11861111 0.15203125 0.13848958]\n",
      "\n",
      "Epoch [12/25]: Evaluation accuracy: 0.212, Eval Hamming loss: 0.396, Eval fbeta: [0.17466667 0.14266667 0.068      0.07333333]\n",
      "Evaluation Confusion matrix: \n",
      " [[[173 195]\n",
      "  [ 54  78]]\n",
      "\n",
      " [[196 216]\n",
      "  [ 19  69]]\n",
      "\n",
      " [[299 103]\n",
      "  [ 66  32]]\n",
      "\n",
      " [[328 103]\n",
      "  [ 35  34]]]\n",
      "\n",
      "Start epoch [13/25]\n",
      "\n",
      "Epoch [13/25]: Train accuracy: 0.436, Hamming loss: 0.208, Loss: 4.076, fbeta: [0.13284722 0.12048611 0.16072917 0.14222222]\n",
      "\n",
      "Epoch [13/25]: Evaluation accuracy: 0.254, Eval Hamming loss: 0.364, Eval fbeta: [0.18533333 0.14666667 0.06533333 0.07066667]\n",
      "Evaluation Confusion matrix: \n",
      " [[[191 177]\n",
      "  [ 49  83]]\n",
      "\n",
      " [[205 207]\n",
      "  [ 17  71]]\n",
      "\n",
      " [[311  91]\n",
      "  [ 67  31]]\n",
      "\n",
      " [[347  84]\n",
      "  [ 36  33]]]\n",
      "\n",
      "Start epoch [14/25]\n",
      "\n",
      "Epoch [14/25]: Train accuracy: 0.451, Hamming loss: 0.198, Loss: 3.978, fbeta: [0.14467014 0.12361111 0.1640625  0.14208333]\n",
      "\n",
      "Epoch [14/25]: Evaluation accuracy: 0.276, Eval Hamming loss: 0.355, Eval fbeta: [0.14266667 0.13733333 0.07066667 0.07066667]\n",
      "Evaluation Confusion matrix: \n",
      " [[[214 154]\n",
      "  [ 67  65]]\n",
      "\n",
      " [[259 153]\n",
      "  [ 22  66]]\n",
      "\n",
      " [[287 115]\n",
      "  [ 65  33]]\n",
      "\n",
      " [[332  99]\n",
      "  [ 36  33]]]\n",
      "\n",
      "Start epoch [15/25]\n",
      "\n",
      "Epoch [15/25]: Train accuracy: 0.454, Hamming loss: 0.200, Loss: 3.952, fbeta: [0.14324653 0.12114583 0.16951389 0.14925347]\n",
      "\n",
      "Epoch [15/25]: Evaluation accuracy: 0.260, Eval Hamming loss: 0.359, Eval fbeta: [0.156      0.136      0.07066667 0.07066667]\n",
      "Evaluation Confusion matrix: \n",
      " [[[199 169]\n",
      "  [ 61  71]]\n",
      "\n",
      " [[256 156]\n",
      "  [ 23  65]]\n",
      "\n",
      " [[292 110]\n",
      "  [ 65  33]]\n",
      "\n",
      " [[333  98]\n",
      "  [ 36  33]]]\n",
      "\n",
      "Start epoch [16/25]\n",
      "\n",
      "Epoch [16/25]: Train accuracy: 0.459, Hamming loss: 0.194, Loss: 3.829, fbeta: [0.13901042 0.12420139 0.16935764 0.14621528]\n",
      "\n",
      "Epoch [16/25]: Evaluation accuracy: 0.266, Eval Hamming loss: 0.361, Eval fbeta: [0.14933333 0.14266667 0.09333333 0.07066667]\n",
      "Evaluation Confusion matrix: \n",
      " [[[211 157]\n",
      "  [ 64  68]]\n",
      "\n",
      " [[247 165]\n",
      "  [ 19  69]]\n",
      "\n",
      " [[276 126]\n",
      "  [ 54  44]]\n",
      "\n",
      " [[329 102]\n",
      "  [ 36  33]]]\n",
      "\n",
      "Start epoch [17/25]\n",
      "\n",
      "Epoch [17/25]: Train accuracy: 0.472, Hamming loss: 0.189, Loss: 3.780, fbeta: [0.14236111 0.12628472 0.17189236 0.15427083]\n",
      "\n",
      "Epoch [17/25]: Evaluation accuracy: 0.310, Eval Hamming loss: 0.327, Eval fbeta: [0.14666667 0.136      0.08266667 0.072     ]\n",
      "Evaluation Confusion matrix: \n",
      " [[[231 137]\n",
      "  [ 65  67]]\n",
      "\n",
      " [[283 129]\n",
      "  [ 23  65]]\n",
      "\n",
      " [[289 113]\n",
      "  [ 59  39]]\n",
      "\n",
      " [[339  92]\n",
      "  [ 36  33]]]\n",
      "\n",
      "Start epoch [18/25]\n",
      "\n",
      "Epoch [18/25]: Train accuracy: 0.471, Hamming loss: 0.187, Loss: 3.737, fbeta: [0.15682292 0.12284722 0.17222222 0.15180556]\n",
      "\n",
      "Epoch [18/25]: Evaluation accuracy: 0.276, Eval Hamming loss: 0.349, Eval fbeta: [0.152      0.13466667 0.08533333 0.072     ]\n",
      "Evaluation Confusion matrix: \n",
      " [[[216 152]\n",
      "  [ 64  68]]\n",
      "\n",
      " [[250 162]\n",
      "  [ 23  65]]\n",
      "\n",
      " [[288 114]\n",
      "  [ 59  39]]\n",
      "\n",
      " [[343  88]\n",
      "  [ 36  33]]]\n",
      "\n",
      "Start epoch [19/25]\n",
      "\n",
      "Epoch [19/25]: Train accuracy: 0.475, Hamming loss: 0.187, Loss: 3.665, fbeta: [0.15274306 0.12232639 0.17538194 0.15180556]\n",
      "\n",
      "Epoch [19/25]: Evaluation accuracy: 0.286, Eval Hamming loss: 0.337, Eval fbeta: [0.136      0.12533333 0.092      0.07066667]\n",
      "Evaluation Confusion matrix: \n",
      " [[[229 139]\n",
      "  [ 70  62]]\n",
      "\n",
      " [[290 122]\n",
      "  [ 27  61]]\n",
      "\n",
      " [[274 128]\n",
      "  [ 55  43]]\n",
      "\n",
      " [[335  96]\n",
      "  [ 36  33]]]\n",
      "\n",
      "Start epoch [20/25]\n",
      "\n",
      "Epoch [20/25]: Train accuracy: 0.475, Hamming loss: 0.184, Loss: 3.607, fbeta: [0.15819444 0.12659722 0.17579861 0.15083333]\n",
      "\n",
      "Epoch [20/25]: Evaluation accuracy: 0.290, Eval Hamming loss: 0.321, Eval fbeta: [0.14133333 0.12933333 0.09333333 0.068     ]\n",
      "Evaluation Confusion matrix: \n",
      " [[[240 128]\n",
      "  [ 68  64]]\n",
      "\n",
      " [[293 119]\n",
      "  [ 26  62]]\n",
      "\n",
      " [[277 125]\n",
      "  [ 54  44]]\n",
      "\n",
      " [[347  84]\n",
      "  [ 38  31]]]\n",
      "\n",
      "Start epoch [21/25]\n",
      "\n",
      "Epoch [21/25]: Train accuracy: 0.474, Hamming loss: 0.182, Loss: 3.507, fbeta: [0.15836806 0.12861111 0.18010417 0.15447917]\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "\n",
      "Epoch [21/25]: Evaluation accuracy: 0.280, Eval Hamming loss: 0.334, Eval fbeta: [0.132      0.12666667 0.07333333 0.072     ]\n",
      "Evaluation Confusion matrix: \n",
      " [[[229 139]\n",
      "  [ 71  61]]\n",
      "\n",
      " [[294 118]\n",
      "  [ 27  61]]\n",
      "\n",
      " [[285 117]\n",
      "  [ 65  33]]\n",
      "\n",
      " [[337  94]\n",
      "  [ 36  33]]]\n",
      "\n",
      "Start epoch [22/25]\n",
      "\n",
      "Epoch [22/25]: Train accuracy: 0.498, Hamming loss: 0.173, Loss: 3.454, fbeta: [0.16527778 0.12604167 0.18036458 0.15538194]\n",
      "\n",
      "Epoch [22/25]: Evaluation accuracy: 0.292, Eval Hamming loss: 0.309, Eval fbeta: [0.124      0.12933333 0.09333333 0.06533333]\n",
      "Evaluation Confusion matrix: \n",
      " [[[256 112]\n",
      "  [ 75  57]]\n",
      "\n",
      " [[307 105]\n",
      "  [ 26  62]]\n",
      "\n",
      " [[281 121]\n",
      "  [ 54  44]]\n",
      "\n",
      " [[345  86]\n",
      "  [ 39  30]]]\n",
      "\n",
      "Start epoch [23/25]\n",
      "\n",
      "Epoch [23/25]: Train accuracy: 0.500, Hamming loss: 0.171, Loss: 3.406, fbeta: [0.16748264 0.12895833 0.18420139 0.15274306]\n",
      "\n",
      "Epoch [23/25]: Evaluation accuracy: 0.264, Eval Hamming loss: 0.340, Eval fbeta: [0.14133333 0.14       0.08       0.072     ]\n",
      "Evaluation Confusion matrix: \n",
      " [[[219 149]\n",
      "  [ 68  64]]\n",
      "\n",
      " [[285 127]\n",
      "  [ 23  65]]\n",
      "\n",
      " [[279 123]\n",
      "  [ 61  37]]\n",
      "\n",
      " [[338  93]\n",
      "  [ 36  33]]]\n",
      "\n",
      "Start epoch [24/25]\n",
      "\n",
      "Epoch [24/25]: Train accuracy: 0.501, Hamming loss: 0.174, Loss: 3.436, fbeta: [0.16475694 0.12986111 0.18034722 0.15378472]\n",
      "\n",
      "Epoch [24/25]: Evaluation accuracy: 0.244, Eval Hamming loss: 0.341, Eval fbeta: [0.14933333 0.128      0.09066667 0.064     ]\n",
      "Evaluation Confusion matrix: \n",
      " [[[212 156]\n",
      "  [ 65  67]]\n",
      "\n",
      " [[267 145]\n",
      "  [ 26  62]]\n",
      "\n",
      " [[286 116]\n",
      "  [ 56  42]]\n",
      "\n",
      " [[352  79]\n",
      "  [ 39  30]]]\n",
      "\n",
      "Start epoch [25/25]\n",
      "\n",
      "Epoch [25/25]: Train accuracy: 0.510, Hamming loss: 0.168, Loss: 3.357, fbeta: [0.16333333 0.12934028 0.18072917 0.15274306]\n",
      "\n",
      "Epoch [25/25]: Evaluation accuracy: 0.262, Eval Hamming loss: 0.330, Eval fbeta: [0.15333333 0.128      0.09333333 0.064     ]\n",
      "Evaluation Confusion matrix: \n",
      " [[[221 147]\n",
      "  [ 62  70]]\n",
      "\n",
      " [[282 130]\n",
      "  [ 26  62]]\n",
      "\n",
      " [[281 121]\n",
      "  [ 54  44]]\n",
      "\n",
      " [[350  81]\n",
      "  [ 39  30]]]\n"
     ]
    }
   ],
   "source": [
    "# Initialize parameters\n",
    "batch_size = 2\n",
    "hidden_size = 32\n",
    "n_features = len(chunk_loader.x_fields)\n",
    "output_size = len(y_fields.split(\", \"))\n",
    "n_layers = 1\n",
    "clip = 50\n",
    "dropout = 0.5\n",
    "learning_rate = 0.001\n",
    "epochs = 25\n",
    "spatial_dropout = False\n",
    "\n",
    "# Check whether system supports CUDA\n",
    "CUDA = torch.cuda.is_available()\n",
    "\n",
    "model = BiGRU(hidden_size, n_features, output_size, n_layers, clip, dropout,\n",
    "              spatial_dropout, bidirectional=True)\n",
    "\n",
    "# Move the model to GPU if possible\n",
    "if CUDA:\n",
    "    model.cuda()\n",
    "\n",
    "weight = torch.FloatTensor(weight)\n",
    "pos_weight = torch.FloatTensor(pos_weight)\n",
    "\n",
    "# model.add_loss_fn(nn.MultiLabelSoftMarginLoss())\n",
    "model.add_loss_fn(nn.BCEWithLogitsLoss(weight=weight, pos_weight=pos_weight))\n",
    "\n",
    "optimizer = torch.optim.Adam(model.parameters(), lr=learning_rate)\n",
    "model.add_optimizer(optimizer)\n",
    "\n",
    "device = torch.device('cuda' if CUDA else 'cpu')\n",
    "\n",
    "model.add_device(device)\n",
    "\n",
    "hamming_avg_loss_list = []\n",
    "eval_hamming_avg_loss_list = []\n",
    "\n",
    "for epoch in range(epochs):\n",
    "    \n",
    "    print('\\nStart epoch [{}/{}]'.format(epoch+1, epochs))\n",
    "    \n",
    "    train_losses_list, train_accuracy_list, fbetas_list, hamming_loss_list = [], [], [], []\n",
    "    eval_accuracy_list, eval_fbetas_list, conf_matrix_list, eval_hamming_loss_list = [], [], [], []\n",
    "    \n",
    "    eval_pred_total = torch.LongTensor()\n",
    "    eval_target_total = torch.LongTensor()\n",
    "    \n",
    "    split = TrainValTestSplit(chunk_loader, val_size=0.1, test_size=0.1)\n",
    "    train_set, val_set, _ = split.get_sets()\n",
    "     \n",
    "    for indices, norm_params in train_set:\n",
    "        \n",
    "        train_iterator = DataLoader(MySQLBatchLoader(indices=indices, norm_params=norm_params, cursor=db_cursor,\n",
    "                                   table=mysql_table_name, db_x_query=db_x_query, y_fields=y_fields,\n",
    "                                   window=window), batch_size=batch_size)\n",
    "\n",
    "        accuracy, hamm_loss, loss, fbeta = model.train_model(train_iterator)\n",
    "        \n",
    "        train_accuracy_list.append(accuracy)\n",
    "        hamming_loss_list.append(hamm_loss)\n",
    "        train_losses_list.append(loss)\n",
    "        fbetas_list.append(fbeta)\n",
    "\n",
    "    train_accuracy = np.mean(train_accuracy_list)\n",
    "    hamming_loss_total = np.mean(hamming_loss_list)\n",
    "    loss_total = np.mean(train_losses_list)\n",
    "    fbeta_total = np.mean(fbetas_list, axis=0)\n",
    "\n",
    "    print('\\nEpoch [{}/{}]: Train accuracy: {:.3f}, Hamming loss: {:.3f}, Loss: {:.3f}, fbeta: {}'\\\n",
    "          .format(epoch+1, epochs, train_accuracy, hamming_loss_total, loss_total, fbeta_total))\n",
    "\n",
    "    for indices, norm_params in val_set:\n",
    "        \n",
    "        val_iterator = DataLoader(MySQLBatchLoader(indices=indices, norm_params=norm_params, cursor=db_cursor,\n",
    "                           table=mysql_table_name, db_x_query=db_x_query, y_fields=y_fields,\n",
    "                           window=window), batch_size=batch_size)\n",
    "        \n",
    "        accuracy, hamm_loss, fbeta, pred, target = model.evaluate_model(val_iterator)\n",
    "        \n",
    "        eval_accuracy_list.append(accuracy)\n",
    "        eval_hamming_loss_list.append(hamm_loss)\n",
    "        eval_fbetas_list.append(fbeta)\n",
    "        \n",
    "        eval_pred_total = torch.cat([eval_pred_total, pred], dim=0)\n",
    "        eval_target_total = torch.cat([eval_target_total, target], dim=0)\n",
    "\n",
    "    eval_conf_matrix = multilabel_confusion_matrix(eval_target_total, eval_pred_total)\n",
    "        \n",
    "    eval_accuracy = np.mean(eval_accuracy_list)\n",
    "    eval_hamming_loss_total = np.mean(eval_hamming_loss_list)\n",
    "    eval_fbeta_total = np.mean(eval_fbetas_list, axis=0)\n",
    "    \n",
    "    print('\\nEpoch [{}/{}]: Evaluation accuracy: {:.3f}, Eval Hamming loss: {:.3f}, Eval fbeta: {}'\\\n",
    "      .format(epoch+1, epochs, eval_accuracy, eval_hamming_loss_total, eval_fbeta_total))\n",
    "    \n",
    "    print(\"Evaluation Confusion matrix: \\n\", eval_conf_matrix)\n",
    "    \n",
    "    hamming_avg_loss_list.append(np.mean(hamming_loss_list))\n",
    "    eval_hamming_avg_loss_list.append(np.mean(eval_hamming_loss_list))\n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 576x360 with 1 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Plot the training and the validation learning curve\n",
    "plt.figure(figsize=(8,5))\n",
    "plt.plot(hamming_avg_loss_list, label='Training loss')\n",
    "plt.plot(eval_hamming_avg_loss_list, label='Evaluation loss')\n",
    "plt.xlabel('Epoch', size=12)\n",
    "plt.ylabel('Hamming Loss', size=12)\n",
    "plt.title('biGRU model learning curves')\n",
    "plt.xticks(ticks=range(epochs+1))\n",
    "plt.legend()\n",
    "plt.show()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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Z3X8RjZ56ps8+8KLrL3Wahzx4+9x6tnjGPWNfTjlDxdw6Pe/W+/qWQbW3X1zJv7ziXpXI39aWipfmoyz+PPmzZvHrvuOZbMd9+JrX12XtddaHYCzzr2Yb3znB5x05rnMmTMHgDffepullxzy6WuXWnIIb741vS71tspMf2M6V5xzNdc8dDnXP3Y1M9+fycPj/13vauVTAXI4yx7iscAmwPsAEfECsGRHG0saI+kRSY+cd955GVUxe7NmfcRPjj6OIw75HoMWXJArr7uZIw4ew53XXcLPDxnDMSf4VFzRjfjRzrTMncdT1/2r3lXJH/cQ94SzuI3evXvz14v/jzuvu4SnnnmeF156hUO/vx83XX4+V15wJu+9/wHjLr0agIjP/5vprEfZGteghQcxYtuN2WOjvdll+O4MXGAg2/zPVvWuVj4VIIezbBDPjog5rU8k9QE6/ClExHkRsX5ErD9mzJhMKpi1T+bO5dCjj2OHbbZk6y02AeDGv/+DrdLH247clKee+W89q2g1tvaum7LqqHW59sdn17sq+eQGcU84izuw0OBBfHX42kx44BGWGLIYkujXrx+77LANTz37PABLLzmEN6Z91iP85rTpnw5ts3xZf9PhTH3tDd595z3mzZ3HPX+/ly+tv2a9q5VPBcjhLBvE90g6ChgoaWvgauCmDI/fUCKCY044g5WWH8a+e/7Pp+VLDFmchx97CoAH//04yw8bWq8qWo19cfO12eQHX+eKA05l7sdzun6BWXU4i0u8M+Nd3v8gGd//8ezZPPDwY6y4/LBPxwVHBHeNv49VVloegC1GbMSNt95JRPDEf55l0KAFWWLIYnWrv/XctMnTWGv4GvQf0B+A9UYM59UXXqtzraxespyh9QvgAOAp4HvALcAFGR6/oTz25NPcdOudrPLFFdh137EA/Ph7+/KbIw7hxDPPZe68efTv149jf34IANPffoc9DjiEmR/OolevXlx61fXccNm5n14SyBrb/5w1luW/tgYLLDqYQx/4X/55+jWM+OFO9O7Xl29feiSQTKy75egLAThkwhn0HzyQ3n37sPo263PpPicy/YXJ9XwLDam909fWJWdxibfensHRx53CvJYWoiXYduSmbLHJhux/8C+Y8e57RASrrbISx/7sYAA2+9pXuff+hxm9+/4MHDCA3x31kzq/A+upZx57jn/ePJ5x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\n",
      "text/plain": [
       "<Figure size 720x720 with 8 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Create the figure and axes instances\n",
    "fig, axes = plt.subplots(2, 2, figsize=(10, 10), sharex=False)\n",
    "label_idx = 0\n",
    "labels = y_fields.split(\", \")\n",
    "\n",
    "# Iterate through rows and columns of a plot\n",
    "for row in range(2):\n",
    "    for col in range(2):\n",
    "        if label_idx <= output_size - 1:\n",
    "            # Confusion matrix\n",
    "            ax = sns.heatmap(eval_conf_matrix[label_idx], fmt='d', annot=True, linewidths=1,\n",
    "                             square=True, ax=axes[row, col])\n",
    "            ax.set_xlabel('Predictions', size=12)\n",
    "            ax.set_ylabel('True Labels', size=12) \n",
    "            ax.set_title('Confusion Matrix for {} label'.format(labels[label_idx].upper()), size=12); \n",
    "            ax.xaxis.set_ticklabels(['False', 'True'])\n",
    "            ax.yaxis.set_ticklabels(['Negative', 'Positive'])\n",
    "            ax.set_ylim(2,0)\n",
    "        else:\n",
    "            # Delete unnecessary axes\n",
    "            fig.delaxes(axes[row, col])\n",
    "        label_idx += 1   \n",
    "        \n",
    "# Automatically adjusts subplot params to fit in figure       \n",
    "plt.tight_layout()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### The generalization error"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [],
   "source": [
    "split = TrainValTestSplit(chunk_loader, val_size=0.12, test_size=0.08)\n",
    "_, _, test_set = split.get_sets()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {},
   "outputs": [],
   "source": [
    "test_accuracy_list, test_fbetas_list, test_conf_matrix_list, test_hamming_loss_list = [], [], [], []\n",
    "\n",
    "test_pred_total = torch.LongTensor()\n",
    "test_target_total = torch.LongTensor()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 22,
   "metadata": {},
   "outputs": [],
   "source": [
    "for indices, norm_params in test_set:\n",
    "    \n",
    "    test_iterator = DataLoader(MySQLBatchLoader(indices=indices, norm_params=norm_params, cursor=db_cursor,\n",
    "                       table=mysql_table_name, db_x_query=db_x_query, y_fields=y_fields,\n",
    "                       window=window), batch_size=batch_size)\n",
    "\n",
    "    accuracy, hamm_loss, fbeta, pred, target = model.evaluate_model(test_iterator)\n",
    "\n",
    "    test_accuracy_list.append(accuracy)\n",
    "    test_hamming_loss_list.append(hamm_loss)\n",
    "    test_fbetas_list.append(fbeta)\n",
    "\n",
    "    test_pred_total = torch.cat([test_pred_total, pred], dim=0)\n",
    "    test_target_total = torch.cat([test_target_total, target], dim=0)\n",
    "    \n",
    "test_conf_matrix = multilabel_confusion_matrix(test_target_total, test_pred_total)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 23,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Test accuracy: 0.216. Test error: 0.317, Test fbeta: [0.10023392 0.03333333 0.14444444 0.09777778]\n"
     ]
    }
   ],
   "source": [
    "print('Test accuracy: {:.3f}. Test error: {:.3f}, Test fbeta: {}'\\\n",
    "      .format(np.mean(test_accuracy_list), np.mean(test_hamming_loss_list), np.mean(test_fbetas_list, axis=0)))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 24,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "image/png": "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\n",
      "text/plain": [
       "<Figure size 720x720 with 8 Axes>"
      ]
     },
     "metadata": {
      "needs_background": "light"
     },
     "output_type": "display_data"
    }
   ],
   "source": [
    "# Create the figure and axes instances\n",
    "fig, axes = plt.subplots(2, 2, figsize=(10, 10), sharex=False)\n",
    "label_idx = 0\n",
    "labels = y_fields.split(\", \")\n",
    "\n",
    "# Iterate through rows and columns of a plot\n",
    "for row in range(2):\n",
    "    for col in range(2):\n",
    "        if label_idx <= output_size - 1:\n",
    "            # Confusion matrix\n",
    "            ax = sns.heatmap(test_conf_matrix[label_idx], fmt='d', annot=True, linewidths=1,\n",
    "                             square=True, ax=axes[row, col])\n",
    "            ax.set_xlabel('Predictions', size=12)\n",
    "            ax.set_ylabel('True labels', size=12) \n",
    "            ax.set_title('Confusion Matrix for {} label'.format(labels[label_idx].upper()), size=12); \n",
    "            ax.xaxis.set_ticklabels(['False', 'True'])\n",
    "            ax.yaxis.set_ticklabels(['Negative', 'Positive'])\n",
    "            ax.set_ylim(2,0)\n",
    "        else:\n",
    "            # Delete unnecessary axes\n",
    "            fig.delaxes(axes[row, col])\n",
    "        label_idx += 1   \n",
    "        \n",
    "# Automatically adjusts subplot params to fit in figure       \n",
    "plt.tight_layout()"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Save the model's learned parameters for Inference"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 37,
   "metadata": {},
   "outputs": [],
   "source": [
    "path = 'model_params.pt'\n",
    "torch.save(model.state_dict(), path)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.3"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
